﻿using System;
using System.Collections.Generic;
using System.Linq;
using RoutineApi.Entities;
using RoutineApi.Models;

namespace RoutineApi.Services
{
    public class PropertyMappingService : IPropertyMappingService
    {
        //映射关系字典
        //一个属性可以映射到多个属性

        //Company 的映射关系字典
        //StringComparer.OrdinalIgnoreCase 表明这个字典的 Key 大小写不敏感
        private readonly Dictionary<string, PropertyMappingValue> _companyPropertyMapping
            = new Dictionary<string, PropertyMappingValue>(StringComparer.OrdinalIgnoreCase)
            {
                    {"Id", new PropertyMappingValue(new List<string> {"Id"})},
                    {"CompanyName", new PropertyMappingValue(new List<string> {"Name"})},
                    {"Country", new PropertyMappingValue(new List<string> {"Country"})},
                    {"Industry", new PropertyMappingValue(new List<string> {"Industry"})},
                    {"Product", new PropertyMappingValue(new List<string> {"Product"})},
                    {
                        "Introduction", new PropertyMappingValue(new List<string> {"Introduction"})
                    } 
            };

        //Employee 的映射关系字典
        //StringComparer.OrdinalIgnoreCase 表明这个字典的 Key 大小写不敏感
        private readonly Dictionary<string, PropertyMappingValue> _employeePropertyMapping
            = new Dictionary<string, PropertyMappingValue>(StringComparer.OrdinalIgnoreCase)
            {
                    {"Id", new PropertyMappingValue(new List<string> {"Id"})},
                    {"CompanyId", new PropertyMappingValue(new List<string> {"CompanyId"})},
                    {"EmployeeNo", new PropertyMappingValue(new List<string> {"EmployeeNo"})},
                    {"Name", new PropertyMappingValue(new List<string> {"FirstName", "LastName"})},
                    {"GenderDisplay", new PropertyMappingValue(new List<string> {"Gender"})},
                    {
                        "Age", new PropertyMappingValue(new List<string> {"DateOfBirth"}, true)
                    } //Age 和 DateOfBirth 排序顺序应该是反转的
            };

        private readonly IList<IPropertyMapping> _propertyMappings = new List<IPropertyMapping>();

        public PropertyMappingService()
        {
            //向列表中添加映射关系
            _propertyMappings.Add(new PropertyMapping<CompanyDto, Company>(_companyPropertyMapping));
            _propertyMappings.Add(new PropertyMapping<EmployeeDto, Employee>(_employeePropertyMapping));
        }

        public Dictionary<string, PropertyMappingValue> GetPropertyMapping<TSource, TDestination>()
        {
            //获得 _propertyMappings 对应泛型的映射关系
            var matchingMapping = _propertyMappings.OfType<PropertyMapping<TSource, TDestination>>();
            var propertyMapping = matchingMapping.ToList();
            if (propertyMapping.Count == 1)
            {
                //如果 TSource 与 TDestination 存在映射关系，返回他们的映射关系字典
                return propertyMapping.First().MappingDictionary;
            }
            throw new Exception($"无法找到唯一的映射关系：{typeof(TSource)},{typeof(TDestination)}");
        }
        public bool ValidMappingExistsFor<TSource, TDestination>(string fields)
        {
            var propertyMapping = GetPropertyMapping<TSource, TDestination>();
            if (string.IsNullOrWhiteSpace(fields))
            {
                return true;
            }
            var fieldAfterSplit = fields.Split(",");
            foreach (var field in fieldAfterSplit)
            {
                var trimmedField = field.Trim();
                var indexOfFirstSpace = trimmedField.IndexOf(" ", StringComparison.Ordinal);
                var propertyName = indexOfFirstSpace == -1 ? trimmedField 
                    : trimmedField.Remove(indexOfFirstSpace);
                if (!propertyMapping.ContainsKey(propertyName))
                {
                    return false;
                }
            }
            return true;
        }
    }
}
